package com.berry.MedCheck;

import android.util.Log;

/**
 * Created by Airay.Rong on 13-12-7.
 */
//发送数据：5字节格式，每秒钟50个包，第7位为同步位。
//字节	位	数据意义
// 1	0～3	     信号强度(0～8)，表示脉搏搏动的强度
//		4	     1＝搜索时间太长，0=OK
//		5	     1＝血氧饱和度下降，0=OK
//		6	     1＝脉搏声音指示
//		7	     同步位，为1               检测到1时，开始记录包，5个包为一个数据。
// 2	0～6	     体积描记图(表示脉搏波形)
//		7	     同步位，为0
// 3	0～3	     柱状图(表示脉搏跳动情况)
//		4	     1＝探头有错误，0=OK
//		5	     1＝搜索脉搏，0=OK
//		6	     脉率第7位
//		7	     同步位，为0
// 4	0～6	     脉率(前6位)
//		7	     同步位，为0
// 5	0～6	     血氧饱和度
//		7	     同步位，为0

public class DataUnpackage {
	private static final boolean SHOWLOG = false;
	private byte[] myWorks;
	private int nWorkLen;
	private int mSignal;            //信号强度(0～8)，表示脉搏搏动的强度
	private int mSearchTimeLong;    //1＝搜索时间太长，0=OK
	private int mSpo2Low;           //1＝血氧饱和度下降，0=OK
	private int mPulseWave;         //体积描记图(表示脉搏波形)
	private int mPI;                // 柱状图(表示脉搏跳动情况)
	private int mProbeError;        //1＝探头有错误，0=OK
	private int mSearchPulse;        //1＝搜索脉搏，0=OK
	private int mSpo2;               // 血氧饱和度
	private int mRealPulseRate;      //  mPulseRate6  +mPulseRate7

	private byte b1;
	private byte b2;
	private byte b3;
	private byte b4;
	private byte b5;



	public DataFullCallback mListener;

	public interface DataFullCallback {
		void onDataFull();
		void onNewData();

		void onSearchTimeLong();

		void onSpo2Low();

		void onProbeError();

		void onSearchPulse();
	}

	public DataUnpackage(DataFullCallback mL) {
		mListener = mL;

	}

	public void testSpo2Value(int byte5) {
		mSpo2 =  (byte5 >> 1);

	}

	public void getNewWork(byte[] values, int len) {
		myWorks = values;
		nWorkLen = len;
		doNewWork();
	}

	private void doNewWork() {
		for (int i = 0; i < nWorkLen; i++) {
			addNewByte(myWorks[i]);
		}
	}

	public void addNewByte(byte newByte) {
		b1 = b2;
		b2 = b3;
		b3 = b4;
		b4 = b5;
		b5 = newByte;
		if (checkSyncBit()) {
			if (SHOWLOG)
				Log.d("BTData", "b1=" + Integer.toHexString(b1) + ",b2=" + Integer.toHexString(b2)
						+ ",b3=" + Integer.toHexString(b3) + ",b4=" + Integer.toHexString(b4)
						+ ",b5=" + Integer.toHexString(b5));
			unPackage();
			if (checkDataUseful()) {
				//Log.d("AAAA", "mPulseWave=" + mPulseWave);
				notifyFullData();
			} else if (mProbeError == 1) {
				notifyProbeError();
				//notifyNewData();
			} else {
				notifyNewData();
			}
			if (SHOWLOG)
				Log.d("BTData", this.toString());

		}

	}

	private boolean checkDataUseful() {
		if (mSearchTimeLong != 0) {
			if (SHOWLOG)
				Log.e("BTData", "Data Error mSearchTimeLong != 0");
			return false;
		}
		if (mProbeError != 0) {
			if (SHOWLOG)
				Log.e("BTData", "Data Error mProbeError != 0");
			return false;
		}
		if (mSearchPulse != 0) {
			if (SHOWLOG)
				Log.e("BTData", "Data Error mSearchPulse != 0");
			return false;
		}
		if (mPulseWave < 0 || mPulseWave > 100) {
			if (SHOWLOG)
				Log.e("BTData", "Data Error mPulseWave < 0 || mPulseWave > 100");
			return false;
		}
		if (mRealPulseRate < Utils.DATA_PR_MIN  || mRealPulseRate > Utils.DATA_PR_MAX) {
			if (SHOWLOG)
				Log.e("BTData", "Data Error mRealPulseRate < 25 || mRealPulseRate > 250");
			return false;
		}
		if (mSpo2 < Utils.DATA_SPO2_MIN || mSpo2 > Utils.DATA_SPO2_MAX) {
			if (SHOWLOG)
				Log.e("BTData", "Data Error mSpo2 < 35 || mSpo2 > 100");
			return false;
		}
		if (mPI < Utils.DATA_PI_MIN || mPI > Utils.DATA_PI_MAX) {
			if (SHOWLOG)
				Log.e("BTData", "Data Error mPI < 0 || mPI > 15");
			return false;
		}
		return true;
	}
	private static final byte BIT_0 = 0x01;  //0000 0001
	private static final byte BIT_1 = 0x02;  //0000 0010
	private static final byte BIT_2 = 0x04;  //0000 0100
	private static final byte BIT_3 = 0x08;  //0000 1000
	private static final byte BIT_4 = 0x10;  //0001 0000
	private static final byte BIT_5 = 0x20;  //0010 0000
	private static final byte BIT_6 = 0x40;  //0100 0000
	//	private static final byte BIT_7  = (byte) 0x80;
	private void unPackage() {
		byte BIT_HEAD_4 = (BIT_0 | BIT_1 | BIT_2 | BIT_3) ;
		byte BIT_HEAD_7 = (BIT_0 | BIT_1 | BIT_2 | BIT_3 | BIT_4 | BIT_5 | BIT_6);
		//byte 1
		mSignal = (int) (b1 & BIT_HEAD_4);                      //第一个字节的0~3位  信号强度
		mSearchTimeLong = (b1 & BIT_4) == BIT_4 ? 1 : 0;        //第一个字节第4位 搜索时间
		mSpo2Low = (b1 & BIT_5) == BIT_5 ? 1 : 0;               //第一个字节第5位Spo2饱和度

		//byte 2
		mPulseWave = (int) (b2 & BIT_HEAD_7);                   //第二个字节0~6， 体积描记图

		//byte 3
		mPI = (int) (b3 & BIT_HEAD_4);                          // 第三个字节0~3，柱状图
		mProbeError = (b3 & BIT_4) == BIT_4 ? 1 : 0;            //第三个字节，第4位，探头错误
		mSearchPulse = (b3 & BIT_5) == BIT_5 ? 1 : 0;           //第三个字节，第5位，搜索脉搏

		//byte 4
		mRealPulseRate =getUnsignedByte((byte) (((b3 & BIT_6)<<1) | b4)) ; //第三个字节，第6位，脉绿的第七位   第4个字节，第 0~6, 脉率前6位

		//byte 5
		mSpo2 =  (int) (b5 & BIT_HEAD_7);                       //第5个字节，第0~6，Spo2
	}

	public int getUnsignedByte (byte data){      //将data字节型数据转换为0~255 (0xFF 即BYTE)。
		return data&0x0FF;
	}

	public int getSpo2() {
		return mSpo2;
	}

	public int getPulseRate() {
		return mRealPulseRate;
	}

	public int getPulseWave() {
		return mPulseWave;
	}

	public float getPI() {
		return getValueSI2PI(mSignal);
	}

	//	信号强度(SI)	灌注指数(PI)
//			0	0.1
//			1	0.2
//			2	0.4
//			3	0.7
//			4	1.4
//			5	2.7
//			6	5.3
//			7	10.3
//			8	20.0
//			15（无效值）	0.0（无效值）
	private float getValueSI2PI(int si) {
		switch (si) {
			case 0:
				return (float) 0.1;
			case 1:
				return (float) 0.2;
			case 2:
				return (float) 0.4;
			case 3:
				return (float) 0.7;
			case 4:
				return (float) 1.4;
			case 5:
				return (float) 2.7;
			case 6:
				return (float) 5.3;
			case 7:
				return (float) 10.3;
			case 8:
				return (float) 20.0;
			default:
				return (float) 0.0;
		}
	}

	public int getSignal() {
		return mSignal;
	}
	private void notifyNewData() {
		if (mListener != null) {
			mListener.onNewData();
		}
	}
	private void notifyFullData() {
		if (mListener != null) {
			mListener.onDataFull();
		}
	}
	private void notifyProbeError() {
		if (mListener != null) {
			mListener.onProbeError();
		}
	}

	private boolean checkSyncBit() {
		//第一个字节最高位是1，其余字节最高位是0
		if (((b1 & 0X80) == 0X80)
				&& ((b2 & 0X80) == 0)
				&& ((b3 & 0X80) == 0)
				&& ((b4 & 0X80) == 0)
				&& ((b5 & 0X80) == 0)) {
			return true;
		}
		return false;
	}

	@Override
	public String toString() {
		return "mSpo2=" + mSpo2
				+ ",mRealPulseRate=" + mRealPulseRate
				+ ",mPulseWave=" + mPulseWave
				+ ",mPI=" + mPI
				+ ",mSignal=" + mSignal
				+ ",mSearchTimeLong=" + mSearchTimeLong
				+ ",mSpo2Low=" + mSpo2Low
				+ ",mProbeError=" + mProbeError
				+ ",mSearchPulse=" + mSearchPulse
				;


	}
}
